package ink.ykb.demo.permission.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import ink.ykb.demo.config.CodeConstant;
import ink.ykb.demo.config.MessageUtil;
import ink.ykb.demo.config.ServiceException;
import ink.ykb.demo.permission.dao.UserDealerDepartmentDao;
import ink.ykb.demo.permission.entity.DealerDepartment;
import ink.ykb.demo.permission.entity.UserDealerDepartment;
import ink.ykb.demo.permission.enums.DepartDataScope;

@Service
public class UserDealerDepartmentServiceImpl implements UserDealerDepartmentService {

	@Autowired
	private MessageUtil messageUtil;
	@Autowired
	private UserDealerDepartmentDao userDealerDepartmentDao;
	@Autowired
	private DealerDepartmentService dealerDepartmentService;
	@Autowired
	private UserDealerDepartmentService self;

	@Caching(evict = {
			@CacheEvict(cacheNames = { "userDealerDepartmentList" }, allEntries = true)
	})
	@Transactional
	@Override
	public void add(UserDealerDepartment userDealerDepartment) {
		if (userDealerDepartment == null) {
			throw new ServiceException(CodeConstant.PARAMS_EMPTY, messageUtil.getMsg(CodeConstant.PARAMS_EMPTY));
		}
		if (userDealerDepartment.getUserId() == null) {
			throw new ServiceException(CodeConstant.PARAMS_EMPTY, messageUtil.getMsg(CodeConstant.PARAMS_EMPTY));
		}
		if (userDealerDepartment.getDealerDepartmentId() == null) {
			throw new ServiceException(CodeConstant.PARAMS_EMPTY, messageUtil.getMsg(CodeConstant.PARAMS_EMPTY));
		}
		if (userDealerDepartment.getScope() == null) {
			throw new ServiceException(CodeConstant.PARAMS_EMPTY, messageUtil.getMsg(CodeConstant.PARAMS_EMPTY));
		}
		UserDealerDepartment dbUserDealerDepartment = userDealerDepartmentDao.getByUserIdAndLock(userDealerDepartment.getUserId());
		if (dbUserDealerDepartment != null) {
			throw new ServiceException(CodeConstant.MUS_112, messageUtil.getMsg(CodeConstant.MUS_112));
		}

		userDealerDepartment.setCreateTime(new Date());
		userDealerDepartmentDao.insert(userDealerDepartment);

	}

	@Caching(evict = { 
			@CacheEvict(cacheNames = { "userDealerDepartment" }, key = "#userDealerDepartmentId"),
			@CacheEvict(cacheNames = { "userDealerDepartmentList" }, allEntries = true),
			@CacheEvict(cacheNames = { "userDealerDepartmentByUserId" }, allEntries = true)
	})
	@Transactional
	@Override
	public void delete(Long userDealerDepartmentId) {
		UserDealerDepartment dbUserDealerDepartment = userDealerDepartmentDao.getById(userDealerDepartmentId);
		if (dbUserDealerDepartment == null) {
			throw new ServiceException(CodeConstant.MUS_114, messageUtil.getMsg(CodeConstant.MUS_114));
		}

		userDealerDepartmentDao.deleteById(dbUserDealerDepartment.getId());
	}

	@Caching(evict = { 
			@CacheEvict(cacheNames = { "userDealerDepartment" }, allEntries = true),
			@CacheEvict(cacheNames = { "userDealerDepartmentList" }, allEntries = true),
			@CacheEvict(cacheNames = { "userDealerDepartmentByUserId" }, key = "#userId")
	})
	@Transactional
	@Override
	public void update(Long userId, Long dealerDepartmentId,Integer scope) {
		UserDealerDepartment userDealerDepartment = this.userDealerDepartmentDao.getByUserId(userId);
		if(userDealerDepartment == null) {
			throw new ServiceException(CodeConstant.MUS_113, messageUtil.getMsg(CodeConstant.MUS_113));
		}
		if(DepartDataScope.getType(scope) != null) {
			userDealerDepartment.setScope(scope);
		}
		userDealerDepartment.setDealerDepartmentId(dealerDepartmentId);
		this.userDealerDepartmentDao.updateById(userDealerDepartment);
	}

	@Cacheable(cacheNames = "userDealerDepartmentList", key = "#dealerDepartmentId")
	@Override
	public List<UserDealerDepartment> getByDealerDepartmentId(Long dealerDepartmentId) {
		return this.userDealerDepartmentDao.getByDealerDepartmentId(dealerDepartmentId);
	}

	@Cacheable(cacheNames = "userDealerDepartment", key = "#userDealerDepartmentId")
	@Override
	public UserDealerDepartment getById(Long userDealerDepartmentId) {
		return this.userDealerDepartmentDao.getById(userDealerDepartmentId);
	}
	
	@Cacheable(cacheNames = "userDealerDepartmentByUserId", key = "#userId")
	@Override
	public UserDealerDepartment getByUserId(Long userId) {
		return this.userDealerDepartmentDao.getByUserId(userId);
	}

	@Override
	public List<UserDealerDepartment> getUserDealerDepartmentAll(Long dealerDepartmentId) {
		//获取整个部门树
		DealerDepartment dbDealerDepartment = dealerDepartmentService.getDealerDepartment(dealerDepartmentId);
		if (dbDealerDepartment == null) {
			throw new ServiceException(CodeConstant.MUS_111, messageUtil.getMsg(CodeConstant.MUS_111));
		}
		List<DealerDepartment> childs = dealerDepartmentService.getDealerDepartmentTree(dbDealerDepartment.getId());
		dbDealerDepartment.setChilds(childs);
		
		List<UserDealerDepartment> list = this.getAllByTree(dbDealerDepartment);
		
		return list;
	}
	
	@Override
	public List<UserDealerDepartment> getAllByTree(DealerDepartment dealerDepartment){
		List<UserDealerDepartment> list = new ArrayList<>();
		
		List<UserDealerDepartment> userDealerDepartmentList = self.getByDealerDepartmentId(dealerDepartment.getId());
		list.addAll(userDealerDepartmentList);
		
		if(dealerDepartment.getChilds() != null && dealerDepartment.getChilds().size() > 0) {
			for (DealerDepartment dd : dealerDepartment.getChilds()) {
				list.addAll(this.getAllByTree(dd));
			}
		}
		
		return list;
	}

}
